package com.lzhpo.core.utils;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.lzhpo.core.domain.CommonVo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author <a href="lijing1@wxchina.com@wxchina.com">Lijin</a>
 * @Description TODO
 * @Date 2019/12/25 13:27
 * @Version 1.0
 **/
public class CalculateUtil {

    private static final Integer[] firsts = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    private static final Integer[] seconds = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    private static final Integer[] thirds = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    /**
     * 质数合集，不是质数就是合数。 1 代表龙头 0 凤尾  1 表示质数 0 表示合数
     */
    private static final Set<Integer> zhishuList =
            Sets.newHashSet(1, 2, 3, 5, 7);



    public static Map<String, String> dragonHeadAndTail = new HashMap<>();

    /**
     * 代码3对应关系
     * 表示 a对应的list中的数字不出现。
     */
    public static Map<Integer, List<Integer>> codeThreeNotMap =
            Maps.newHashMap();
    /**
     * 代码4对应关系
     * 表示 a对应的list中的数字不出现。
     */
    public static Map<Integer, List<Integer>> codeFourNotMap =
            Maps.newHashMap();
    /**
     * 代码3页面展示某位对应的ok数字
     */
    public static Map<Integer, List<Integer>> codeThreeMapDesc =
            Maps.newHashMap();
    /**
     * 排列5代码3页面展示某位对应的ok数字
     */
    public static Map<Integer, List<Integer>> codeThreeFiveMapDesc =
            Maps.newHashMap();
    /**
     * 代码4页面展示某位对应的ok数字
     */
    public static Map<Integer, List<Integer>> codeFourMapDesc =
            Maps.newHashMap();

    /**
     * 北京飞艇代码5页面展示某位对应的ok数字
     */
    public static Map<Integer, List<Integer>> boatCodeFiveFiveMapDesc =
            Maps.newHashMap();
    /**
     * 拍列5代码5页面展示某位对应的ok数字
     */
    public static Map<Integer, List<Integer>> rangeCodeFiveFiveMapDesc =
            Maps.newHashMap();


    public static Map<Integer, List<Integer>> codeFiveNotMap =
            Maps.newHashMap();



    static {

        codeFiveNotMap.put(1, Lists.newArrayList(8));
        codeFiveNotMap.put(2, Lists.newArrayList(3));
        codeFiveNotMap.put(3, Lists.newArrayList(4));
        codeFiveNotMap.put(4, Lists.newArrayList(1));
        codeFiveNotMap.put(5, Lists.newArrayList(10));
        codeFiveNotMap.put(6, Lists.newArrayList(5));
        codeFiveNotMap.put(7, Lists.newArrayList(2));
        codeFiveNotMap.put(8, Lists.newArrayList(9));
        codeFiveNotMap.put(9, Lists.newArrayList(7));
        codeFiveNotMap.put(10, Lists.newArrayList(6));


        dragonHeadAndTail.put("1:1", "头质");
        dragonHeadAndTail.put("1:0", "头合");
        dragonHeadAndTail.put("0:1", "尾质");
        dragonHeadAndTail.put("0:0", "尾合");

        /**
         *选择后代码4对应不出的数字
         */
       /* codeFourNotMap.put(1, Lists.newArrayList(6, 10));
        codeFourNotMap.put(2, Lists.newArrayList(1, 7));
        codeFourNotMap.put(3, Lists.newArrayList(2, 8));
        codeFourNotMap.put(4, Lists.newArrayList(3, 9));
        codeFourNotMap.put(5, Lists.newArrayList(4, 10));
        codeFourNotMap.put(6, Lists.newArrayList(1, 5));
        codeFourNotMap.put(7, Lists.newArrayList(2, 6));
        codeFourNotMap.put(8, Lists.newArrayList(3, 7));
        codeFourNotMap.put(9, Lists.newArrayList(4, 8));
        codeFourNotMap.put(10, Lists.newArrayList(5, 9));*/
        codeFourNotMap.put(1, Lists.newArrayList(2, 6));
        codeFourNotMap.put(2, Lists.newArrayList(3, 7));
        codeFourNotMap.put(3, Lists.newArrayList(4, 8));
        codeFourNotMap.put(4, Lists.newArrayList(5, 9));
        codeFourNotMap.put(5, Lists.newArrayList(6, 10));
        codeFourNotMap.put(6, Lists.newArrayList(1, 7));
        codeFourNotMap.put(7, Lists.newArrayList(2, 8));
        codeFourNotMap.put(8, Lists.newArrayList(3, 9));
        codeFourNotMap.put(9, Lists.newArrayList(4, 10));
        codeFourNotMap.put(10, Lists.newArrayList(1, 5));


        codeThreeNotMap.put(1, Lists.newArrayList(2, 5, 8));
        codeThreeNotMap.put(2, Lists.newArrayList(3, 6, 9));
        codeThreeNotMap.put(3, Lists.newArrayList(4, 7, 10));
        codeThreeNotMap.put(4, Lists.newArrayList(1, 2, 5));
        codeThreeNotMap.put(5, Lists.newArrayList(3, 6, 8));
        codeThreeNotMap.put(6, Lists.newArrayList(4, 7, 9));
        codeThreeNotMap.put(7, Lists.newArrayList(1, 5, 10));
        codeThreeNotMap.put(8, Lists.newArrayList(2, 6, 8));
        codeThreeNotMap.put(9, Lists.newArrayList(3, 7, 9));
        codeThreeNotMap.put(10, Lists.newArrayList(1, 4, 10));

        //

        /**
         * 1 : 123 56 89
         * 2：23  567 910
         * 3：1 34 678 10
         * 4：12 45 789
         * 5：23 56 8910
         * 6：1 34 67 910
         * 7：12 45 78 10
         * 8：234 67 910
         * 9：1 345 78 10
         * 10：12 456 89
         */
        codeThreeMapDesc.put(1,
                Lists.newArrayList(1, 2, 3, 5, 6, 8, 9));
        codeThreeMapDesc.put(2,
                Lists.newArrayList(2, 3, 5, 6, 7, 9, 10));
        codeThreeMapDesc.put(3,
                Lists.newArrayList(1, 3, 4, 6, 7, 8, 10));
        codeThreeMapDesc.put(4,
                Lists.newArrayList(1, 2, 4, 5, 7, 8, 9));
        codeThreeMapDesc.put(5,
                Lists.newArrayList(2, 3, 5, 6, 8, 9, 10));
        codeThreeMapDesc.put(6,
                Lists.newArrayList(1, 3, 4, 6, 7, 9, 10));
        codeThreeMapDesc.put(7,
                Lists.newArrayList(1, 2, 4, 5, 7, 8, 10));
        codeThreeMapDesc.put(8,
                Lists.newArrayList(2, 3, 4, 6, 7, 9, 10));
        codeThreeMapDesc.put(9,
                Lists.newArrayList(1, 3, 4, 5, 7, 8, 10));
        codeThreeMapDesc.put(10,
                Lists.newArrayList(1, 2, 4, 5, 6, 8, 9));

        /**
         * 排列5 代码3
         */
        codeThreeFiveMapDesc.put(0,Lists.newArrayList(0,1,3,4,5,7,8));
        codeThreeFiveMapDesc.put(1,Lists.newArrayList(1,2,4,5,6,8,9));
        codeThreeFiveMapDesc.put(2,Lists.newArrayList(0,2,3,5,6,7,9));
        codeThreeFiveMapDesc.put(3,Lists.newArrayList(0,1,3,4,6,7,8));
        codeThreeFiveMapDesc.put(4,Lists.newArrayList(1,2,4,5,7,8,9));
        codeThreeFiveMapDesc.put(5,Lists.newArrayList(0,2,3,5,6,8,9));
        codeThreeFiveMapDesc.put(6,Lists.newArrayList(0,1,3,4,6,7,9));
        codeThreeFiveMapDesc.put(7,Lists.newArrayList(0,1,2,4,5,7,8));
        codeThreeFiveMapDesc.put(8,Lists.newArrayList(1,2,3,5,6,8,9));
        codeThreeFiveMapDesc.put(9,Lists.newArrayList(0,2,3,4,6,7,9));



        codeFourMapDesc.put(1,
                Lists.newArrayList(1, 2, 3, 4, 5, 7, 8, 9));
        codeFourMapDesc.put(2,
                Lists.newArrayList(2, 3, 4, 5, 6, 8, 9, 10));
        codeFourMapDesc.put(3,
                Lists.newArrayList(1, 3, 4, 5, 6, 7, 9, 10));
        codeFourMapDesc.put(4,
                Lists.newArrayList(1, 2, 4, 5, 6, 7, 8, 10));
        codeFourMapDesc.put(5,
                Lists.newArrayList(1, 2, 3, 5, 6, 7, 8, 9));
        codeFourMapDesc.put(6,
                Lists.newArrayList(2, 3, 4, 6, 7, 8, 9, 10));
        codeFourMapDesc.put(7,
                Lists.newArrayList(1, 3, 4, 5, 7, 8, 9, 10));
        codeFourMapDesc.put(8,
                Lists.newArrayList(1, 2, 4, 5, 6, 8, 9, 10));
        codeFourMapDesc.put(9,
                Lists.newArrayList(1, 2, 3, 5, 6, 7, 9, 10));
        codeFourMapDesc.put(10,
                Lists.newArrayList(1, 2, 3, 4, 6, 7, 8, 10));

        boatCodeFiveFiveMapDesc.put(1,Lists.newArrayList(1,2,3,5,6,7,8,9,10));
        boatCodeFiveFiveMapDesc.put(2,Lists.newArrayList(1,2,3,4,5,6,8,9,10));
        boatCodeFiveFiveMapDesc.put(3,Lists.newArrayList(1,3,4,5,6,7,8,9,10));
        boatCodeFiveFiveMapDesc.put(4,Lists.newArrayList(1,2,4,5,6,7,8,9,10));
        boatCodeFiveFiveMapDesc.put(5,Lists.newArrayList(1,2,3,4,5,7,8,9,10));
        boatCodeFiveFiveMapDesc.put(6,Lists.newArrayList(1,2,3,4,5,6,7,8,9));
        boatCodeFiveFiveMapDesc.put(7,Lists.newArrayList(1,2,3,4,5,6,7,8,10));
        boatCodeFiveFiveMapDesc.put(8,Lists.newArrayList(2,3,4,5,6,7,8,9,10));
        boatCodeFiveFiveMapDesc.put(9,Lists.newArrayList(1,2,3,4,5,6,7,9,10));
        boatCodeFiveFiveMapDesc.put(10,Lists.newArrayList(1,2,3,4,6,7,8,9,10));


        rangeCodeFiveFiveMapDesc.put(0,
                Lists.newArrayList(0,1,2,3,4,6,7,8,9));
        rangeCodeFiveFiveMapDesc.put(1,
                Lists.newArrayList(0,1,2,3,5,6,7,8,9));
        rangeCodeFiveFiveMapDesc.put(2,
                Lists.newArrayList(0,1,2,3,4,5,6,8,9));
        rangeCodeFiveFiveMapDesc.put(3,
                Lists.newArrayList(0,1,3,4,5,6,7,8,9));
        rangeCodeFiveFiveMapDesc.put(4,
                Lists.newArrayList(0,1,2,4,5,6,7,8,9));
        rangeCodeFiveFiveMapDesc.put(5,
                Lists.newArrayList(0,1,2,3,4,5,7,8,9));
        rangeCodeFiveFiveMapDesc.put(6,
                Lists.newArrayList(1,2,3,4,5,6,7,8,9));
        rangeCodeFiveFiveMapDesc.put(7,
                Lists.newArrayList(0,1,2,3,4,5,6,7,8));
        rangeCodeFiveFiveMapDesc.put(8,
                Lists.newArrayList(0,2,3,4,5,6,7,8,9));
        rangeCodeFiveFiveMapDesc.put(9,
                Lists.newArrayList(0,1,2,3,4,5,6,7,9));


    }


    /**
     * 计算胆码num中的号码出现的情况。
     *
     * @param nums       预测的号码
     * @param occurTimes 出现的次数
     * @return
     */
    public static Set<String> calcDanMa(List<Integer> nums, List<Integer> occurTimes) {
        if (CollectionUtils.isEmpty(occurTimes)) {
            return new HashSet<>();
        }
        Set<String> result = new HashSet<>();
        for (Integer first : firsts) {
            for (Integer second : seconds) {
                for (Integer third : thirds) {
                    if (first.equals(second) || first.equals(third) || second.equals(third)) {
                        continue;
                    }
                    List<Integer> temp = Lists.newArrayList(first, second, third);
                    if (checkIfFillCondition(temp, nums, occurTimes)) {
                        result.add((first == 10 ? first : "0" + first) + "-" + (second == 10 ? second : "0" + second)
                                + "-" + (third == 10 ? third : "0" + third));
                    }
                }

            }
        }
        return result;
    }


    public static Set<String> calcNoCondition() {
        Set<String> result = new HashSet<>();
        for (Integer first : firsts) {
            for (Integer second : seconds) {
                for (Integer third : thirds) {
                    if (first.equals(second) || first.equals(third) || second.equals(third)) {
                        continue;
                    }
                    result.add((first == 10 ? first : "0" + first) + "-" + (second == 10 ? second : "0" + second)
                            + "-" + (third == 10 ? third : "0" + third));
                }

            }
        }
        return result;
    }

    /**
     * 计算定位码出现的情况 123  456  789  0 （1,2）
     * occurTimes 0,（1,2,3）
     *
     * @return
     */
    public static Set<String> calcDingweiMa(List<Integer> firstPredict,
                                            List<Integer> secondPredict,
                                            List<Integer> thirdPredict,
                                            List<Integer> occurTimes

    ) {
        if (CollectionUtils.isEmpty(occurTimes)) {
            return new HashSet<>();
        }
        Set<String> result = new HashSet<>();
        for (Integer occur : occurTimes) {
            for (Integer first : firsts) {
                for (Integer second : seconds) {
                    for (Integer third : thirds) {
                        //组合的三个数不能相同
                        if (first.equals(second) || first.equals(third) || second.equals(third)) {
                            continue;
                        }
                        if (checkFillConditionSelect(occur, first, second, third, firstPredict, secondPredict, thirdPredict)) {
                            result.add((first == 10 ? first : "0" + first) + "-" + (second == 10 ? second : "0" + second)
                                    + "-" + (third == 10 ? third : "0" + third));
                            continue;
                        }


                    }
                }
            }
        }
        return result;
    }

    /***
     * 检查定位码满足所选的几个条件
     * @param occur
     * @param first
     * @param second
     * @param third
     * @param firstPredict
     * @param secondPredict
     * @param thirdPredict
     * @return
     */
    private static boolean checkFillConditionSelect(Integer occur,
                                                    Integer first, Integer second, Integer third,
                                                    List<Integer> firstPredict,
                                                    List<Integer> secondPredict,
                                                    List<Integer> thirdPredict) {

        int i = 0;
        if (firstPredict.contains(first)) {
            i++;
        }
        if (secondPredict.contains(second)) {
            i++;
        }
        if (thirdPredict.contains(third)) {
            i++;
        }
        return occur == i;
    }


    //是否满足出现次数
    private static boolean checkIfFillCondition(List<Integer> temp, List<Integer> nums, List<Integer> occurTimes) {
        temp.retainAll(nums);
        if (occurTimes.contains(temp.size())) {
            return true;
        }
        return false;
    }

    /**
     * 计算龙头凤尾的条件
     *
     * @param headAndTail 龙头凤尾质合
     * @param headArea
     * @param tailArea
     * @param area0
     * @param area1
     * @param area2
     * @param occurs
     * @return
     */
    public static Set<String> calcDragon(
            String headAndTail,
            String headArea,
            String tailArea,
            String area0,
            String area1,
            String area2,
            String occurs
    ) {

        Set<String> result = new HashSet<>();
        Splitter splitter = Splitter.on(";");
        //龙头凤尾的质，合。及出现次数
        List<String> headAndTailList = splitter.splitToList(headAndTail);
        List<Integer> headAreaList = intCommonsStrToList(headArea);
        List<Integer> tailAreaList = intCommonsStrToList(tailArea);
        List<Integer> area0List = intCommonsStrToList(area0);
        List<Integer> area1List = intCommonsStrToList(area1);
        List<Integer> area2List = intCommonsStrToList(area2);
        //occursList 为空时前台阻止提交
        List<Integer> occursList = intCommonsStrToList(occurs);
        for (Integer occur : occursList) {
            for (Integer first : firsts) {
                for (Integer second : seconds) {
                    for (Integer third : thirds) {
                        //组合的三个数不能相同
                        if (first.equals(second) || first.equals(third) || second.equals(third)) {
                            continue;
                        }
                        List<Integer> eles = Lists.newArrayList(first, second, third);
                        //occur表示需要满足的条件个数
                        int fillCount = 0;
                        //龙头凤尾质合满足
                        if (fillHeadAndTail(headAndTailList, eles)) {
                            fillCount++;
                        }
                        //龙头满足012路条件
                        if (fillHeadArea012(headAreaList, eles)) {
                            fillCount++;
                        }
                        if (fillTailArea012(tailAreaList, eles)) {
                            fillCount++;
                        }
                        if (fillArea0Num(area0List, eles)) {
                            fillCount++;
                        }
                        if (fillArea1Num(area1List, eles)) {
                            fillCount++;
                        }
                        if (fillArea2Num(area2List, eles)) {
                            fillCount++;
                        }
                        if (fillCount == occur) {
                            result.add((first == 10 ? first : "0" + first) + "-" + (second == 10 ? second : "0" + second)
                                    + "-" + (third == 10 ? third : "0" + third));
                        }

                    }
                }
            }
        }
        return result;

    }

    private static boolean fillArea2Num(List<Integer> area2List, List<Integer> eles) {
        List<Integer> temp=eles.stream().distinct().collect(Collectors.toList());
        int count = 0;
        for (Integer a : temp) {
            if (a % 3 == 2) {
                count++;
            }
        }
        return area2List.contains(count);
    }

    private static boolean fillArea1Num(List<Integer> area1List, List<Integer> eles) {
        List<Integer> temp=eles.stream().distinct().collect(Collectors.toList());
        int count = 0;
        for (Integer a : temp) {
            if (a % 3 == 1) {
                count++;
            }
        }
        return area1List.contains(count);
    }

    private static boolean fillArea0Num(List<Integer> area0List, List<Integer> eles) {
        List<Integer> temp=eles.stream().distinct().collect(Collectors.toList());
        int count = 0;
        for (Integer a : temp) {
            if (a % 3 == 0) {
                count++;
            }
        }
        return area0List.contains(count);
    }


    private static boolean fillTailArea012(List<Integer> tailAreaList, List<Integer> eles) {
        int tail = Collections.max(eles);
        if (tailAreaList.contains(tail % 3)) {
            return true;
        }
        return false;
    }

    /**
     * 龙头满足 0 1 2 路条件，1，2 表示龙头在 1 2 路都符合条件
     *
     * @param headAreaList
     * @param eles
     * @return
     */
    private static boolean fillHeadArea012(List<Integer> headAreaList, List<Integer> eles) {
        int head = Collections.min(eles);
        if (headAreaList.contains(head % 3)) {
            return true;
        }
        return false;
    }

    /**
     * 数字满足龙头凤尾质合，及条件。
     *
     * @param headAndTailList
     * @param eles
     * @return
     */
    private static boolean fillHeadAndTail(List<String> headAndTailList,
                                           List<Integer> eles) {
        int head = Collections.min(eles);
        int tail = Collections.max(eles);
        //龙头分为都没选。
        if (headAndTailList.get(0).split(":").length < 2 &&
                headAndTailList.get(1).split(":").length < 2
        ) {
            return false;
        }
//        if (headAndTailList.get(1).split(":").length<2){
//            return  false;
//        }
        //龙头是zhishu
        int fill = 0;
        //如果龙头是质数
        if (headAndTailList.get(0).split(":").length == 2) {
            if (headAndTailList.get(0).split(":")[1].equals("1")) {
                if (zhishuList.contains(head)) {
                    fill++;
                }
            } else {
                if (!zhishuList.contains(head)) {
                    fill++;
                }
            }
        }

        //如果凤尾是质数
        if (headAndTailList.get(1).split(":").length == 2) {
            if (headAndTailList.get(1).split(":")[1].equals("1")) {
                if (zhishuList.contains(tail)) {
                    fill++;
                }
            } else {
                if (!zhishuList.contains(tail)) {
                    fill++;
                }
            }
        }

        List<Integer> occus = intCommonsStrToList(headAndTailList.get(2));
        return occus.contains(fill);
    }

    /**
     * 容错算法
     * @param newCollection
     * @param collections
     * @return
     */

    public static List<String> getIdentical(List<String> var1,
                                            List<String> var2,
                                            List<String> var3,
                                            int type){
        List<String> res=new ArrayList<>();
        List<String> allList=new ArrayList<>();
        allList.addAll(var1);
        allList.addAll(var2);
        allList.addAll(var3);
        allList=allList.stream().distinct().collect(Collectors.toList());
        switch (type){
            case 0:
                res =allList.stream().filter(
                        e->var1.contains(e) &&
                            var2.contains(var2) &&
                            var3.contains(e)
                ).collect(Collectors.toList());
                break;
            case 1:
                res=allList.stream().filter(e->(var1.contains(e)
                        && var2.contains(e)) || (var1.contains(e)
                        && var3.contains(e)) || (var2.contains(e)
                        && var3.contains(e))
                        && !(var1.contains(e)
                        && var2.contains(e) && var3.contains(e))).collect(Collectors.toList());
                break;
            case 2:
                res=allList.stream().filter(e->!(var1.contains(e) && var2.contains(e) && var3.contains(e))).collect(Collectors.toList());
                break;
            case 3:
                res=allList.stream().filter(e->!getIdentical(var1,var2,var3,1).contains(e)).collect(Collectors.toList());
                break;
        }
        return res;
    }

    /***
     * 求和collections的交集
     * @param newCollection
     * @param collections
     * @return  newCollection
     */
    public static List<String> findIntersectionNew(List<String> newCollection,
                                                   List<List<String>> collections) {
        boolean first = true;
        for (List<String> collection : collections) {
            if (first) {
                newCollection.addAll(collection);
                first = false;
            } else {
                newCollection.retainAll(collection);
            }
        }
        if (CollectionUtils.isNotEmpty(newCollection)) {
            newCollection = newCollection.stream().distinct().collect(Collectors.toList());
        }
        return newCollection;
    }

    /**
     * 将字符串分割的整数转为list
     *
     * @param regionsPredict
     * @return
     */
    public static List<Integer> intCommonsStrToList(String regionsPredict) {

        List<String> myList = Splitter.on(",")
                .omitEmptyStrings()
                .splitToList(regionsPredict);
        if (CollectionUtils.isEmpty(myList)) {
            return Lists.newArrayList();
        }
        return myList.stream().map(s -> Integer.valueOf(s)).collect(Collectors.toList());
    }

    public static List<String> intCommonsStrToStrList(String str) {
        if (StringUtils.isBlank(str)){
            return Lists.newArrayList();
        }
        List<String> myList = Splitter.on(",")
                .omitEmptyStrings()
                .splitToList(str);
        return myList;
    }

    /**
     * 判断一个数是质数
     * true  质数
     * false 合数
     */

    public static boolean isPrimeNumber(Integer num) {
        return zhishuList.contains(num);
    }



    /**
     * 求出第几路元素第个数
     *
     * @param numsThree
     * @param i
     * @return
     */
    public static int getAreaNums(List<Integer> numsThree, int i) {
        //去重 699 算 0 路有两个而不是3个
        numsThree=numsThree.stream().distinct().collect(Collectors.toList());
        int count = 0;
        for (Integer e : numsThree
        ) {
            if (e % 3 == i) {
                count++;
            }
        }
        return count;

    }

    public static Set<String> calcSumValue(String sumValues,
                                           String valueFirst,
                                           String valueSecond,
                                           Integer preTermSumValue,
                                           String occurs) {

        Set<String> result = new HashSet<>();
        List<Integer> sumValuesLists = intCommonsStrToList(sumValues);
        List<Integer> occursList = intCommonsStrToList(occurs);
        /**
         * 出现次数
         */
        for (Integer occur : occursList) {
            for (Integer first : firsts) {
                for (Integer second : seconds) {
                    for (Integer third : thirds) {
                        //组合的三个数不能相同
                        if (first.equals(second) || first.equals(third) || second.equals(third)) {
                            continue;
                        }
                        int fillCount = 0;
                        int sumTemp = first + second + third;
                        Integer sumValue = sumTemp % 10;
                        //合值条件
                        if (CollectionUtils.isNotEmpty(sumValuesLists)
                                && sumValuesLists.contains(sumValue)) {
                            fillCount++;
                        }
                        if ("左".equals(valueFirst) && sumValue + 1 == preTermSumValue) {
                            //坐传
                            fillCount++;
                        }
                        if ("右".equals(valueFirst) && sumValue == preTermSumValue + 1) {
                            //右传
                            fillCount++;
                        }
                        if ("断".equals(valueFirst)
                                && (sumValue + 1 != preTermSumValue)
                                && (sumValue != preTermSumValue + 1)
                        ) {
                            //右传
                            fillCount++;
                        }
                        if ("落".equals(valueSecond) && sumValue == preTermSumValue) {
                            fillCount++;
                        }
                        if ("断".equals(valueSecond) && sumValue != preTermSumValue) {
                            fillCount++;
                        }
                        if (fillCount == occur) {
                            result.add((first == 10 ? first : "0" + first) + "-" + (second == 10 ? second : "0" + second)
                                    + "-" + (third == 10 ? third : "0" + third));
                        }
                    }
                }
            }
        }
        return result;
    }


    public static int[] getDistanceValue(String prizeNo01, String prizeNo02, String prizeNo03) {
        return getDistanceValue(Integer.valueOf(prizeNo01),
                Integer.valueOf(prizeNo02),
                Integer.valueOf(prizeNo03)
        );
    }

    public static int getSpanValue(CommonVo entity) {
        String spanValueTemp =
                Joiner.on(",").join(entity.getPrizeNo01(), entity.getPrizeNo02(), entity.getPrizeNo03());
        List<Integer> list =
                CalculateUtil.intCommonsStrToList(spanValueTemp);
        Collections.sort(list);
        int minValue = Collections.min(list);
        int maxValue = Collections.max(list);
        return maxValue - minValue;
    }

    public static int getSpanValue(String no1, String no2, String no3) {
        CommonVo vo = new CommonVo();
        vo.setPrizeNo01(no1);
        vo.setPrizeNo02(no2);
        vo.setPrizeNo03(no3);
        return getSpanValue(vo);
    }

    public static int[] getDistanceValue(int prizeNo01, int prizeNo02, int prizeNo03) {
        int[] unSortedArr = {prizeNo01, prizeNo02, prizeNo03};
        Arrays.parallelSort(unSortedArr);
        int minValue = unSortedArr[0];
        int maxValue = unSortedArr[2];
        int[] arr = new int[2];
        arr[0] = (minValue - 1) + (10 - maxValue);
        arr[1] = Math.max(unSortedArr[1] - unSortedArr[0], unSortedArr[2] - unSortedArr[1]);
        return arr;
    }

    public static Set<String> calcBorderSum(String distances,//反边球
                                            String maxIntervals,//临码跨
                                            String borderSums,//边临和
                                            String valueFirst,//传断
                                            String valueSecond,//断落
                                            String occursAll,
                                            String occursMix,
                                            int preTermSumValue) {

        List<Integer> distanceList = intCommonsStrToList(distances);
        List<Integer> intervalList = intCommonsStrToList(maxIntervals);
        List<Integer> borderSumList = intCommonsStrToList(borderSums);
        List<Integer> occursList = intCommonsStrToList(occursAll);
        List<Integer> occursMixList = intCommonsStrToList(occursMix);


        Set<String> result = new HashSet<>();
        for (Integer occur : occursList) {
            for (Integer first : firsts) {
                for (Integer second : seconds) {
                    for (Integer third : thirds) {
                        //组合的三个数不能相同
                        if (first.equals(second) || first.equals(third) || second.equals(third)) {
                            continue;
                        }
                        int fillCount = 0;
                        int[] sumValueArr = getDistanceValue(first, second, third);
                        int disValue = sumValueArr[0];
                        int intervalValue = sumValueArr[1];
                        int borderValue = disValue + intervalValue;
                        //满足边临和 传断 断落
                        if (fillBorderValueMix(borderSumList,
                                borderValue,
                                preTermSumValue, valueFirst, valueSecond, occursMixList)) {
                            fillCount++;
                        }
                        //反边球
                        if (distanceList.contains(disValue)) {
                            fillCount++;
                        }
                        //临码跨
                        if (intervalList.contains(intervalValue)) {
                            fillCount++;
                        }
                        if (fillCount == occur) {
                            result.add((first == 10 ? first : "0" + first) + "-" + (second == 10 ? second : "0" + second)
                                    + "-" + (third == 10 ? third : "0" + third));
                        }
                    }
                }
            }
        }

        return result;

    }

    private static boolean fillBorderValueMix(List<Integer> borderSumList,
                                              int borderValue,
                                              int preTermSumValue,
                                              String valueFirst,
                                              String valueSecond,
                                              List<Integer> occursMixList) {
        int occur = 0;
        if (borderSumList.contains(borderValue)) {
            occur++;
        }
        if ("left".equals(valueFirst) && borderValue == (preTermSumValue - 1)) {
            occur++;
        } else if ("right".equals(valueFirst) && borderValue == (preTermSumValue + 1)) {
            occur++;
        } else if ("break1".equals(valueFirst)
                && (borderValue + 1 != preTermSumValue)
                && (borderValue != preTermSumValue + 1)
        ) {
            occur++;
        }
        if ("fall".equals(valueSecond) && borderValue == preTermSumValue) {
            occur++;
        } else if ("break2".equals(valueSecond) && borderValue != preTermSumValue) {
            occur++;
        }
        return occursMixList.contains(occur);
    }

    public static Set<String> calcSpanValue(String spanValues,
                                            String valueFirst,
                                            String valueSecond,
                                            String occursAll,
                                            int preTermSumValue) {

        List<Integer> spanSumList = intCommonsStrToList(spanValues);
        List<Integer> occursList = intCommonsStrToList(occursAll);
        Set<String> result = new HashSet<>();
        for (Integer occur : occursList) {
            for (Integer first : firsts) {
                for (Integer second : seconds) {
                    for (Integer third : thirds) {
                        //组合的三个数不能相同
                        if (first.equals(second) || first.equals(third) || second.equals(third)) {
                            continue;
                        }
                        int fillCount = 0;
                        int spanValue = getSpanValue(
                                String.valueOf(first),
                                String.valueOf(second),
                                String.valueOf(third)
                        );
                        if (spanSumList.contains(spanValue)) {
                            fillCount++;
                        }

                        if ("left".equals(valueFirst) && spanValue == (preTermSumValue - 1)) {
                            fillCount++;
                        } else if ("right".equals(valueFirst) && spanValue == (preTermSumValue + 1)) {
                            fillCount++;
                        } else if ("break1".equals(valueFirst)
                                && (spanValue + 1 != preTermSumValue)
                                && (spanValue != preTermSumValue + 1)
                        ) {
                            fillCount++;
                        }
                        if ("fall".equals(valueSecond) && spanValue == preTermSumValue) {
                            fillCount++;
                        } else if ("break2".equals(valueSecond) && spanValue != preTermSumValue) {
                            fillCount++;
                        }

                        if (fillCount == occur) {
                            result.add((first == 10 ? first : "0" + first) + "-" + (second == 10 ? second : "0" + second)
                                    + "-" + (third == 10 ? third : "0" + third));
                        }
                    }
                }
            }
        }

        return result;


    }

    /**
     * 计算代码3
     *
     * @param fristsParam        第一位选择的号码,逗号分隔
     * @param firstOccurs，第一位的出次
     * @param secondsParam
     * @param secondOccurs
     * @param thirdsParam
     * @param thirdOccurs
     * @param occurs
     * @return
     */
    public static Set<String> calcCodeThreeValue(String fristsParam,
                                                 String firstOccurs,
                                                 String secondsParam,
                                                 String secondOccurs,
                                                 String thirdsParam,
                                                 String thirdOccurs,
                                                 String occurs, int type) {
        List<Integer> bigOccurList = intCommonsStrToList(occurs);
        List<Integer> firstList = intCommonsStrToList(fristsParam);
        List<Integer> firstOccurList = intCommonsStrToList(firstOccurs);
        List<Integer> secondList = intCommonsStrToList(secondsParam);
        List<Integer> secondOccurList = intCommonsStrToList(secondOccurs);
        List<Integer> thirdList = intCommonsStrToList(thirdsParam);
        List<Integer> thirdOccurList = intCommonsStrToList(thirdOccurs);
        Set<String> result = new HashSet<>();
        for (Integer occur : bigOccurList) {
            for (Integer first : firsts) {
                for (Integer second : seconds) {
                    for (Integer third : thirds) {
                        if (first.equals(second) || first.equals(third) || second.equals(third)) {
                            continue;
                        }
                        int fillCount = 0;
                        if (fillCode3Condition(firstList, firstOccurList, first, type)) {
                            fillCount++;
                        }
                        if (fillCode3Condition(secondList, secondOccurList, second, type)) {
                            fillCount++;
                        }
                        if (fillCode3Condition(thirdList, thirdOccurList, third, type)) {
                            fillCount++;
                        }
                        if (fillCount == occur) {
                            result.add((first == 10 ? first : "0" + first) + "-" + (second == 10 ? second : "0" + second)
                                    + "-" + (third == 10 ? third : "0" + third));
                        }
                    }
                }
            }
        }
        return result;
    }

    /**
     * @param firstList      第一位选择的预测数字(实际上是该数字对应的m,n,q在第一位不出现)
     * @param firstOccurList 出 几
     * @param first          当前实际第一位数字
     * @return
     */
    private static boolean fillCode3Condition(List<Integer> firstList,
                                              List<Integer> firstOccurList,
                                              Integer first, int type) {
        int occur = 0;
        Map<Integer, List<Integer>> mapTemp = codeThreeNotMap;
        if (type == 7) {
            mapTemp = codeThreeNotMap;
        }
        if (type == 8) {
            mapTemp = codeFourNotMap;
        }
        for (Integer num : firstList) {
            if (!mapTemp.get(num).contains(first)) {
                occur++;
            }
        }
        return firstOccurList.contains(occur);
    }

    public static Set<String> calcCodeFiveValue(String fristsParam,
                                                String firstOccurs,
                                                String secondsParam,
                                                String secondOccurs,
                                                String thirdsParam,
                                                String thirdOccurs,
                                                String occurs
    ) {
        List<Integer> bigOccurList = intCommonsStrToList(occurs);
        List<Integer> firstList = intCommonsStrToList(fristsParam);
        List<Integer> firstOccurList = intCommonsStrToList(firstOccurs);
        List<Integer> secondList = intCommonsStrToList(secondsParam);
        List<Integer> secondOccurList = intCommonsStrToList(secondOccurs);
        List<Integer> thirdList = intCommonsStrToList(thirdsParam);
        List<Integer> thirdOccurList = intCommonsStrToList(thirdOccurs);
        Set<String> result = new HashSet<>();
        for (Integer occur : bigOccurList) {
            for (Integer first : firsts) {
                for (Integer second : seconds) {
                    for (Integer third : thirds) {

                        if (first.equals(second) || first.equals(third) || second.equals(third)) {
                            continue;
                        }

                        int fillCount = 0;
                        if (fillCode5Condition(firstList, firstOccurList, first)) {
                            fillCount++;
                        }
                        if (fillCode5Condition(secondList, secondOccurList, second)) {
                            fillCount++;
                        }
                        if (fillCode5Condition(thirdList, thirdOccurList, third)) {
                            fillCount++;
                        }
                        if (fillCount == occur) {
                            result.add((first == 10 ? first : "0" + first) + "-" + (second == 10 ? second : "0" + second)
                                    + "-" + (third == 10 ? third : "0" + third));

                        }
                    }
                }
            }
        }
        return result;
    }

    private static boolean fillCode5Condition(List<Integer> firstList,
                                              List<Integer> firstOccurList,
                                              Integer first) {
        int occur = 0;
        Map<Integer, List<Integer>> mapTemp = codeFiveNotMap;
        for (Integer num : firstList) {
            if (!mapTemp.get(num).contains(first)) {
                occur++;
            }
        }
        return firstOccurList.contains(occur);
    }

}